package cd.cdyb.sms.config;

import cd.cdyb.sms.interceptor.WhitelistInterceptor;
import cd.cdyb.sms.service.WhiteListService;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Resource
    private WhiteListService whiteListService;

    /**
     * 消息转换器配置
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {


        //1.需要定义一个convert转换消息的对象;
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper om = jacksonConverter.getObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        om.setLocale(Locale.CHINA);
        om.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        om.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {

                String fieldName = gen.getOutputContext().getCurrentName();
                try {
                    //反射获取字段类型
                    Field field = getField(gen.getCurrentValue().getClass(), fieldName);
                    if (field != null) {
                        if (Objects.equals(field.getType(), String.class)
                                || Objects.equals(field.getType(), Integer.class)
                                || Objects.equals(field.getType(), BigDecimal.class)
                                || Objects.equals(field.getType(), Long.class)
                                || Objects.equals(field.getType(), Date.class)) {
                            //字符串型空值""
                            gen.writeString("");
                            return;
                        } else if (Objects.equals(field.getType(), List.class)) {
                            //列表型空值返回[]
                            gen.writeStartArray();
                            gen.writeEndArray();
                            return;
                        } else if (Objects.equals(field.getType(), Map.class)) {
                            //map型空值返回{}
                            gen.writeStartObject();
                            gen.writeEndObject();
                            return;
                        }
                    }

                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                //默认返回""
                gen.writeNull();
            }
        });
//        om.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, true);
        om.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);

        List<MediaType> mediaTypeList = new ArrayList<>();

        Charset charset = Charset.forName("UTF-8");
//        mediaTypeList.add(new MediaType("text", "plain", charset));
        mediaTypeList.add(new MediaType("application", "json", charset));
        jacksonConverter.setSupportedMediaTypes(mediaTypeList);
        converters.add(jacksonConverter);


    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WhitelistInterceptor(whiteListService));
    }

    private Field getField(Class cla, String fieldName) throws NoSuchFieldException {
        try {
            Field field = cla.getDeclaredField(fieldName);
            return field;
        } catch (NoSuchFieldException e) {
            Class superclass = cla.getSuperclass();
            if (superclass != null) {
                return getField(superclass, fieldName);
            }
        }
        return null;
    }
}
